/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.cip.esymons.eventos.beans;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.cip.esymons.colegiatura.be.Preinscripcion;
import org.cip.esymons.eventos.bc.CursoDelegate;
import org.cip.esymons.eventos.bc.CursoAdapter;
import org.cip.esymons.eventos.bc.InstructorEventoAdapter;
import org.cip.esymons.eventos.bc.InstructorEventoDelegate;
import org.cip.esymons.eventos.bc.InstructorModuloAdapter;
import org.cip.esymons.eventos.bc.InstructorModuloDelegate;
import org.cip.esymons.eventos.bc.ModuloCursoDelegate;
import org.cip.esymons.eventos.bc.PreEventoDelegate;
import org.cip.esymons.eventos.be.Curso;
import org.cip.esymons.eventos.be.InstructorEvento;
import org.cip.esymons.eventos.be.InstructorModulo;
import org.cip.esymons.eventos.be.ModuloCurso;
//import org.cip.esymons.eventos.be.Preevento;
import org.cip.esymons.general.util.ControladorAbstracto;
import org.cip.esymons.general.util.Utiles;


/**
 *
 * @author lizardo
 */
public class CursoController {
    private CursoDelegate delegado;
    private ModuloCursoDelegate delegadoModulo;
    private InstructorEventoDelegate delegadoInstructorEvento;
    private InstructorModuloDelegate delegadoInstructorModulo;
    private Curso curso;
    private CursoAdapter cursoAdapter;
    private ModuloCurso modulo;
    private InstructorEvento instructor;
    private InstructorEventoAdapter instructorAdapter;
    private InstructorModulo instructorModulo;
    private InstructorModuloAdapter instructorModuloAdapter;
    private List<CursoAdapter> listaCurso;
    private List<ModuloCurso> listaModulo;
    private List<InstructorEvento> listaInstructor;
    private List<InstructorModuloAdapter> listaInstructorModulo;
    private Integer modCodigo;
    private Integer ineCodigo;
    private Integer nroModulos;
    private String mensaje;

    private List<Preinscripcion> listaPreInscripcion;
    private Date fechaIniCol;
    private Date fechaFinCol;
    private String total;
    
    /*********************** Constructor de la clase *************************/
    public CursoController() {
        inicializar();
    }

    
    /*************************** Sets y Gettters *****************************/
    public String getTotal() {
        return total;
    }

    public void setTotal(String total) {
        this.total = total;
    }
    
    public CursoAdapter getCursoAdapter() {
        return cursoAdapter;
    }
    public void setCursoAdapter(CursoAdapter cursoAdapter) {
        this.cursoAdapter = cursoAdapter;
    }

    public List<CursoAdapter> getListaCurso() {
        return listaCurso;
    }
    public void setListaCurso(List<CursoAdapter> listaCurso) {
        this.listaCurso = listaCurso;
    }

    public CursoDelegate getDelegado() {
        return delegado;
    }

    public String getMensaje() {
        return mensaje;
    }
    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

    public ModuloCursoDelegate getDelegadoModulo() {
        return delegadoModulo;
    }
    public void setDelegadoModulo(ModuloCursoDelegate delegadoModulo) {
        this.delegadoModulo = delegadoModulo;
    }

    public ModuloCurso getModulo() {
        return modulo;
    }
    public void setModulo(ModuloCurso modulo) {
        this.modulo = modulo;
    }

    public List<ModuloCurso> getListaModulo() {
        return listaModulo;
    }
    public void setListaModulo(List<ModuloCurso> listaModulo) {
        this.listaModulo = listaModulo;
    }

    public Integer getNroModulos() {
        obtenerNroModulos();
        return nroModulos;
    }

    public void setNroModulos(Integer nroModulos) {
        this.nroModulos = nroModulos;
    }

    public Integer getModCodigo() {
        //nombreModulo =
        return modCodigo;
    }
    public void setModCodigo(Integer modCodigo) {
        this.modCodigo = modCodigo;
    }

    public Curso getCurso() {
        return curso;
    }
    public void setCurso(Curso curso) {
        this.curso = curso;
    }

    public List<InstructorEvento> getListaInstructor() {
        return listaInstructor;
    }
    public void setListaInstructor(List<InstructorEvento> listaInstructor) {
        this.listaInstructor = listaInstructor;
    }

    public InstructorEvento getInstructor() {
        return instructor;
    }
    public void setInstructor(InstructorEvento instructor) {
        this.instructor = instructor;
    }
    
    public InstructorEventoAdapter getInstructorAdapter() {
        return instructorAdapter;
    }
    public void setInstructorAdapter(InstructorEventoAdapter instructorAdapter) {
        this.instructorAdapter = instructorAdapter;
    }

    public InstructorModulo getInstructorModulo() {
        return instructorModulo;
    }
    public void setInstructorModulo(InstructorModulo instructorModulo) {
        this.instructorModulo = instructorModulo;
    }

    public InstructorEventoDelegate getDelegadoInstructorEvento() {
        return delegadoInstructorEvento;
    }
    public void setDelegadoInstructorEvento(InstructorEventoDelegate delegadoInstructorEvento) {
        this.delegadoInstructorEvento = delegadoInstructorEvento;
    }

    public InstructorModuloDelegate getDelegadoInstructorModulo() {
        return delegadoInstructorModulo;
    }
    public void setDelegadoInstructorModulo(InstructorModuloDelegate delegadoInstructorModulo) {
        this.delegadoInstructorModulo = delegadoInstructorModulo;
    }

    public InstructorModuloAdapter getInstructorModuloAdapter() {
        return instructorModuloAdapter;
    }
    public void setInstructorModuloAdapter(InstructorModuloAdapter instructorModuloAdapter) {
        this.instructorModuloAdapter = instructorModuloAdapter;
    }

    public List<InstructorModuloAdapter> getListaInstructorModulo() {
        try{
            modCodigo = modulo.getModCodigo();
            modCodigo = (modCodigo == null ? 0 : modCodigo);
            listaInstructorModulo = delegadoInstructorModulo.listarInstructorModulo(modCodigo);
        }catch(Exception ex){
            System.out.println("Error: " + ex.getMessage());
            listaInstructorModulo = new ArrayList<InstructorModuloAdapter>();
        }
        return listaInstructorModulo;
    }
    public void setListaInstructorModulo(List<InstructorModuloAdapter> listaInstructorModulo) {
        this.listaInstructorModulo = listaInstructorModulo;
    }

    public Integer getIneCodigo() {
        return ineCodigo;
    }
    public void setIneCodigo(Integer ineCodigo) {
        this.ineCodigo = ineCodigo;
    }






    public Date getFechaFinCol() {
        return fechaFinCol;
    }
    public void setFechaFinCol(Date fechaFinCol) {
        this.fechaFinCol = fechaFinCol;
    }

    public Date getFechaIniCol() {
        return fechaIniCol;
    }
    public void setFechaIniCol(Date fechaIniCol) {
        this.fechaIniCol = fechaIniCol;
    }

    public List<Preinscripcion> getListaPreInscripcion() {
        return listaPreInscripcion;
    }
    public void setListaPreInscripcion(List<Preinscripcion> listaPreInscripcion) {
        this.listaPreInscripcion = listaPreInscripcion;
    }





    /**************************** Metodos ************************************/
    public String inicializar() {
        curso = new Curso();
        delegado = new CursoDelegate();
        delegadoInstructorModulo = new InstructorModuloDelegate();
        delegadoModulo = new ModuloCursoDelegate();
        delegadoInstructorEvento = new InstructorEventoDelegate();
        listaCurso = new ArrayList<CursoAdapter>();
        listar();
        return "";
    }

    public String listar() {
        listaCurso = delegado.listarCursos();
        total = Utiles.totalRegistro(listaCurso, "curso(s) registrado(s)");
        return "listar";
    }

    public String agregarInstructores() {

        return "nuevo_instructor";
    }

    public String agregarModulos() {
        try {
            nuevo();
            //listaModulo = delegadoModulo.listarModuloXCurso(cursoAdapter.getCodigo());
            listaModulo = delegadoModulo.listarModulo(cursoAdapter.getCodigo());
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No se puede listar los módulos. ", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        return "nuevo_modulo";
    }

    public String nuevo() {
        modulo = new ModuloCurso();
        listaModulo = new ArrayList<ModuloCurso>();
        return null;
    }

    public String registrarModulo() {
        try {
            if (verificar()) {
                System.out.print("codCurso: " + cursoAdapter.getCodigo());
                curso.setEveCodigo(cursoAdapter.getCodigo());
                modulo.setCurCodigo(curso);
                System.out.println("DATOS");
                System.out.println("-----");
                System.out.println("modCodigo: " + modulo.getModCodigo());
                System.out.println("modModulo: " + modulo.getModAcronimo());
                System.out.println("modNombre: " + modulo.getModNombre());
                System.out.println("modTipo: " + modulo.getModTipo());
                System.out.println("modPeriodo: " + modulo.getPeriodo());
                delegadoModulo.create(modulo);
                inicializar();
            }
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No se puede agregar módulo. ", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        agregarModulos();
        return null;
    }

    public String editarModulo() {
        try {
            if (verificarFechasValidas()) {
                System.out.print("codCurso: " + cursoAdapter.getCodigo());
                curso.setEveCodigo(cursoAdapter.getCodigo());
                modulo.setCurCodigo(curso);
                System.out.println("DATOS");
                System.out.println("-----");
                System.out.println("modCodigo: " + modulo.getModCodigo());
                System.out.println("modModulo: " + modulo.getModAcronimo());
                System.out.println("modNombre: " + modulo.getModNombre());
                System.out.println("modTipo: " + modulo.getModTipo());
                System.out.println("modPeriodo: " + modulo.getPeriodo());
                delegadoModulo.edit(modulo);
                inicializar();
            }
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No se puede editar módulo. ", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        agregarModulos();
        return null;
    }

    public String obtenerNroModulos() {
        try {
            //nroModulos = (Integer)delegadoModulo.cantidadModulos(cursoAdapter.getCodigo());
            PreEventoDelegate delegadoPrevento = new PreEventoDelegate();
            nroModulos = delegadoPrevento.findID(cursoAdapter.getCodigo()).getPreNroModulos();
            delegadoPrevento = null;
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No devuelve el nro de modulos. " + ex.getMessage(), FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
            nroModulos = 0;
        }
        return null;
    }

    public boolean verificar() {
        if (verificarNumeroModulos()) {
            if (verificarFechas()) {
                if (verificarRangoFechas()) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean verificarFechasValidas() {
        if (verificarFechas()) {
            if (verificarRangoFechas()) {
                return true;
            }
        }
        return false;
    }

//    public boolean verificarNumeroModulos() {
//        try {
//            Preevento preevento = new Preevento();
//            preevento = delegadoModulo.busPreevento(cursoAdapter.getCodigo());
//            if (preevento != null) nroModulos = preevento.getPreNroModulos();
//            Integer canModulos = delegadoModulo.cantidadModulos(cursoAdapter.getCodigo());
//            nroModulos = (nroModulos == null) ? 0 : nroModulos;
//            canModulos = (canModulos == null) ? 0 : canModulos;
//            if (nroModulos <= canModulos) {
//                mostrarMensaje("ERROR: ", "Solo puede ingresar hasta " + canModulos + " módulos!", FacesMessage.SEVERITY_ERROR);
//                return false;
//            }
//            return true;
//        } catch (Exception ex) {
//            mostrarMensaje("ERROR: ", "Al verificar la cantidad de módulos", FacesMessage.SEVERITY_ERROR);
//            System.out.println("FATAL: " + ex.getMessage());
//            return false;
//        }
//    }

    public boolean verificarNumeroModulos() {
        try {
            if (!listaModulo.isEmpty()) {
                if (listaModulo.size() < nroModulos) {
                    return true;
                } else {
                    mostrarMensaje("ERROR: ", "Solo puede ingresar hasta " + nroModulos + " módulos!", FacesMessage.SEVERITY_ERROR);
                    return false;
                }
            } else {
                System.out.println("WARN: No hay modulos del curso.");
                return true;
            }
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "Al verificar la cantidad de módulos.", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
            return false;
        }
    }

    public boolean verificarFechas() {
        Date fechaFin = modulo.getModfechaFin();
        Date fechaInicio = modulo.getModfechaInicio();
        //DATE.compareTo devuelve 1 si la fecha inicial es menor a la final
        //               devuelve -1 si la fecha inicial es mayor a la final
        //               devuelve 0 si ambas fechas son iguales
        int resultado = fechaFin.compareTo(fechaInicio);
        if (resultado == -1) {
            mostrarMensaje("ERROR: ", "La fecha de inicio no puede ser mayor que la fecha fin", FacesMessage.SEVERITY_ERROR);
            return false;
        }
        return true;
    }

    public boolean verificarRangoFechas() {
        try {
            if (modulo != null) {
                Date fechaInicio = modulo.getModfechaInicio();
                Date fechaFin = modulo.getModfechaFin();
                if (!delegadoModulo.verificarRangosFecha(fechaInicio, fechaFin, cursoAdapter.getCodigo())) {
                    mostrarMensaje("ERROR: ", "Ingrese rango de  fechas del Curso!", FacesMessage.SEVERITY_ERROR);
                    return false;
                }
            } else {
                mostrarMensaje("ERROR: ", "No existen fechas del módulo!", FacesMessage.SEVERITY_ERROR);
                return false;
            }
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "Error al verificar Rangos de Fechas. " + ex.getMessage(), FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        return true;
    }

    public String registrarInstructor() {
        try {
            //modulo.setModCodigo(modCodigo);
            System.out.println("ineCodigo: " + ineCodigo);
            instructor = delegadoInstructorEvento.find(ineCodigo);
            instructorModulo.setIneCodigo(instructor);
            instructorModulo.setModCodigo(modulo);
            System.out.println("DATOS");
            System.out.println("-----");
            System.out.println("modulo: " + modulo);
            System.out.println("instructor: " + instructor);
            System.out.println("inmCodigo: " + instructorModulo.getInmCodigo());
            System.out.println("modCodigo: " + instructorModulo.getModCodigo().getModCodigo());
            System.out.println("ineCodigo: " + instructorModulo.getIneCodigo().getIneCodigo());
            delegadoInstructorModulo.create(instructorModulo);
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No se puede agregar instructor. " + ex.getMessage(), FacesMessage.SEVERITY_ERROR);
        }
        verInstructores();
        return null;
    }

    public String eliminarModulo() {
        try {
            delegadoModulo.remove(modulo);
            //listaModulo = delegadoModulo.listarModuloXCurso(cursoAdapter.getCodigo());
            listaModulo = delegadoModulo.listarModulo(cursoAdapter.getCodigo());
            modulo = new ModuloCurso();
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No se pudo eliminar el módulo. ", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        return null;
    }

    public String verInstructores() {
        instructorModulo = new InstructorModulo();
        listaInstructorModulo = new ArrayList<InstructorModuloAdapter>();
        System.out.println(modulo.getModCodigo());
        listaInstructorModulo = delegadoInstructorModulo.listarInstructorModulo(modulo.getModCodigo());
        return null;
    }

    public String eliminarInstructor() {
        //Aqui hay un adapter por eso primero se busca el objeto y luego se ejecuta la accion
        instructorModulo = delegadoInstructorModulo.buscarXCodigo(instructorModuloAdapter.getCodigo());
        System.out.println("Objeto instructor: " + instructorModulo.getIneCodigo());
        System.out.println("Objeto modulo: " + instructorModulo.getModCodigo());
        delegadoInstructorModulo.remove(instructorModulo);
        listaInstructorModulo = delegadoInstructorModulo.listarInstructorModulo(cursoAdapter.getCodigo());
        instructorModulo = new InstructorModulo();
        return null;
    }

    public String actualizarNotaMinima() {
        try {
            for (CursoAdapter ca : listaCurso) {
                Curso cur = new Curso();
                cur = delegado.find(ca.getCodigo());
                if (cur != null) {
                    cur.setCurNotaMinima(ca.getNotaMinima());
                    delegado.edit(cur);
                } else {
                    System.out.println("NotaMinima[" + ca.getCodigo() + "] no actualizada...");
                }
            }
            mostrarMensaje("INFO: ", "Se actualizo sastifactoriamente las notas minima por curso.", FacesMessage.SEVERITY_INFO);
            inicializar();
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "No se pudo actualizar la nota minima.", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        return null;
    }

    public SelectItem[] getComboInstructorEventos() {
        try {
            System.out.println("Ingreso 1");
            Integer curCodigo = cursoAdapter.getCodigo();
            System.out.println("curCodigo: " + curCodigo);
            SelectItem[] selects = null;
            List<InstructorEventoAdapter> listaInstructorEvento = delegadoInstructorEvento.listarInstructorEvento(curCodigo);
            selects = new SelectItem[listaInstructorEvento.size()];
            int cont = 0;
            for (InstructorEventoAdapter instructorEvento : listaInstructorEvento) {
                SelectItem item = new SelectItem(instructorEvento.getCodigo(), instructorEvento.getNombreCompleto());
                selects[cont++] = item;
            }
            return selects;
        } catch (Exception e) {
            System.out.println("Ingreso Error: " + e.getMessage());
            SelectItem[] selects = new SelectItem[1];
            SelectItem item = new SelectItem(null, "No existen Instructores");
            selects[0] = item;
            return selects;
        }
    }

    public void mostrarMensaje(String resumen, String detalle, FacesMessage.Severity severidad) {
        try {
            FacesMessage fm = new FacesMessage(severidad, resumen, detalle);
            FacesContext.getCurrentInstance().addMessage(fm.toString(), fm);
        } catch (Exception e) {
            FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage());
            FacesContext.getCurrentInstance().addMessage(fm.toString(), fm);
        }
    }

    public void mostrarAdvertencia(String resumen, String detalle, FacesMessage.Severity severidad) {
        try {
            FacesMessage fm = new FacesMessage(severidad, resumen, detalle);
            FacesContext.getCurrentInstance().addMessage(fm.toString(), fm);
        } catch (Exception e) {
            FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_WARN, e.getMessage(), e.getMessage());
            FacesContext.getCurrentInstance().addMessage(fm.toString(), fm);
        }
    }

    public String listarPreinscripcion() {
        CursoDelegate delegadoPreinscripcion = new CursoDelegate();
        try {
            listaPreInscripcion = delegadoPreinscripcion.listaPorFechasYConDireccion(fechaIniCol, fechaFinCol);
        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "Al listar la inscripción", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }
        return null;
    }

    public String exportar() {
        listarPreinscripcion();
        try {
            HttpServletRequest request =  ControladorAbstracto.getRequest();
            HttpServletResponse response = ControladorAbstracto.getResponse();

            response.setContentType("application/vnd.ms-excel");
            HSSFWorkbook wb = new HSSFWorkbook();                   //crea el libro
            HSSFSheet sheet = wb.createSheet("Hoja Preinscritos");  //crea hoja
            
            HSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);

            HSSFRow rowH = sheet.createRow((short) 0);  //crea la cabecera
            HSSFCell a1 = rowH.createCell((short) 0);   //crea A1
            HSSFCell b1 = rowH.createCell((short) 1);   //crea B1
            HSSFCell c1 = rowH.createCell((short) 2);   //crea C1
            a1.setCellValue("Nombre");
            b1.setCellValue("Paterno");
            c1.setCellValue("Materno");

            for (int i=0; i<listaPreInscripcion.size(); i++) {
                HSSFRow row = sheet.createRow((short) i+1);  //crea la fila
                HSSFCell A1 = row.createCell((short) 0);   //crea A1
                HSSFCell B1 = row.createCell((short) 1);   //crea B1
                HSSFCell C1 = row.createCell((short) 2);   //crea C1
                String nombre = listaPreInscripcion.get(i).getPerCodigo().getPerNombres();
                String paterno = listaPreInscripcion.get(i).getPerCodigo().getPerapellidoPaterno();
                String materno = listaPreInscripcion.get(i).getPerCodigo().getPerapellidoMaterno();
                nombre = (nombre != null) ? nombre : "";
                paterno = (paterno != null) ? paterno : "";
                materno = (materno != null) ? materno : "";
                A1.setCellValue(nombre);
                B1.setCellValue(paterno);
                C1.setCellValue(materno);
            }

            ServletOutputStream out = response.getOutputStream();
            wb.write(out);
            out.close();

        } catch (Exception ex) {
            mostrarMensaje("ERROR: ", "Al generar la exportacion", FacesMessage.SEVERITY_ERROR);
            System.out.println("FATAL: " + ex.getMessage());
        }

        return null;
    }

}
